﻿using SXICE.Core.Domains;
using SXICE.Core.Helpers;
using SXICE.Core.Models;
using SXICE.IRepository;
using SXICE.IService;
using SXICE.IService.Models;
using System;
using System.Collections.Generic;
using System.Linq;

namespace SXICE.Service
{
    /// <summary>
    /// 权限DTO
    /// </summary>
    public class RightsService : IRightsService
    {
        private readonly IRightsRepository rightsRepository;

        public RightsService(IRightsRepository rightsRepository)
        {
            this.rightsRepository = rightsRepository;
        }

        public ReturnResult AddRights(int roleId, List<int> menuIds)
        {
            if (!rightsRepository.RoleExists(roleId).Success)
                return ServiceErrors.ROLE_IS_EXISTED.ToResult("角色不存在");
            menuIds?.RemoveAll(c => !rightsRepository.Menus.Any(d => d.Id == c));
            return rightsRepository.AddRights(roleId, menuIds);
        }

        /// <summary>
        /// 验证角色名称
        /// </summary>
        /// <param name="name">要验证的名称</param>
        /// <returns>结果</returns>
        private ReturnResult ValidateRoleName(string name)
        {
            if (name.IsNullOrEmpty())
                return ServiceErrors.ROLE_NAME_IS_EMPTY.ToResult("角色名称不能为空");
            if (name.Length < 2 || name.Length > 20)
                return ServiceErrors.ROLE_NAME_LENGTH_IS_WRONG.ToResult("角色名称长度必须为2-20位");
            return true.ToResult();
        }

        public ReturnResult AddRole(string name)
        {
            var result = ValidateRoleName(name);
            if (!result.Success)
                return result;
            result = rightsRepository.RoleExists(name);
            if (result.Success)
                return ServiceErrors.ROLE_IS_EXISTED.ToResult("角色名称已存在");
            return rightsRepository.AddRole(name);
        }

        public ReturnResult DeleteRole(int id)
        {
            if (RuntimeHelper.Resolve<IDoctorRepository>().ExistsByRoleId(id).Success)
                return ServiceErrors.ROLE_BINDING_USERS.ToResult("此角色还绑定了医生，请先将此角色的医生改为其他角色后再删除");
            return rightsRepository.DeleteRole(id);
        }

        public ReturnResult<List<Menu>> GetMenus()
        {
            return rightsRepository.Menus.ToResult();
        }

        private void FindParent(Menu menu, List<Menu> myMenus, List<Menu> menus)
        {
            if (menu.ParentId > 0)
            {
                var parent = menus.Find(c => c.Id == menu.ParentId);
                //如果不存在则添加
                if (!myMenus.Any(c => c.Id == parent.Id))
                    myMenus.Add(parent);
            }
        }

        public ReturnResult<List<Menu>> GetMenusByRoleId(int roleId)
        {
            var rights = rightsRepository.GetRights(roleId);
            if (!rights.Success)
                return rights.ToErrorResult<List<Menu>>();
            var menus = rightsRepository.Menus;
            var myMenus = menus.FindAll(c => rights.Result.Any(d => d.MenuId == c.Id));
            var count = myMenus.Count;
            for (int i = 0; i < count; i++)
                FindParent(myMenus[i], myMenus, menus);
            return myMenus.ToResult();
        }

        public ReturnResult<List<RightsDTO>> GetRightsDTO(int roleId)
        {
            var roles = rightsRepository.GetRoles();
            if (!roles.Success)
                return roles.ToErrorResult<List<RightsDTO>>();
            var rights = rightsRepository.GetRights(roleId);
            if (!rights.Success)
                return rights.ToErrorResult<List<RightsDTO>>();
            var menus = rightsRepository.Menus;
            return rights.Result.Select(c => new RightsDTO
            {
                Id = c.Id,
                MenuId = c.MenuId,
                MenuName = menus.Find(d => d.Id == c.MenuId)?.Name,
                RoleId = c.RoleId,
                RoleName = roles.Result.Find(d => d.Id == c.RoleId)?.Name
            }).ToList().ToResult();
        }

        public ReturnResult<List<Roles>> GetRoles()
        {
            return rightsRepository.GetRoles();
        }

        public ReturnResult UpdateRole(Roles roles)
        {
            var result = ValidateRoleName(roles?.Name);
            if (!result.Success)
                return result;
            if (!rightsRepository.RoleExists(roles.Id).Success)
                return ServiceErrors.ROLE_IS_NOT_EXISTED.ToResult();
            if (rightsRepository.RoleExists(roles.Name).Success)
                return ServiceErrors.ROLE_IS_EXISTED.ToResult("角色名称已存在");
            return rightsRepository.UpdateRole(roles);
        }

        public ReturnResult<List<Rights>> GetRights(int roleId)
        {
            return rightsRepository.GetRights(roleId);
        }

        public ReturnResult HasRights(int roleId, string code)
        {
            return rightsRepository.HasRights(roleId, code);
        }
    }
}